/*
* ICommerceSession.java
*
* Created on April 12, 2001, 9:54 AM
*/

/*
(C) Copyright MarketLive. 2006. All rights reserved.
MarketLive is a trademark of MarketLive, Inc.
Warning: This computer program is protected by copyright law and international treaties.
Unauthorized reproduction or distribution of this program, or any portion of it, may result
in severe civil and criminal penalties, and will be prosecuted to the maximum extent
possible under the law.
*/


package org.marketlive.biz.session.context;

import org.marketlive.entity.account.ICustomer;
import org.marketlive.entity.IPrimaryKey;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import java.util.Locale;
import java.util.List;
import java.math.BigDecimal;


/**
 * Represents a user's session information while browsing a commerce site.
 *
 * @see ICommerceSessionManager
 */
public interface ICommerceSession extends Serializable {

    /**
     * Key used to store current user's session in HttpSession object.
     */
    String COMMERCE_SESSION = "COMMERCE_SESSION";

    /**
     * Returns the manager for this <code>ICommerceSession</code>.
     * @return the <code>ICommerceSessionManager</code> for this <code>ICommerceSession</code>
     */
    ICommerceSessionManager getCommerceSessionManager();

    /**
     * Sets the manager for this <code>ICommerceSession</code>.
     * @param manager the <code>ICommerceSessionManager</code> for this <code>ICommerceSession</code>
     */
    void setCommerceSessionManager(ICommerceSessionManager manager);
    
    /**
     * Attempts to log in the customer within the specified user id and password.
     * Returns true if the login was successful.  A successful login also
     * sets the customer cookie.
     *
     * @param userID the login name of the user
     * @param password the password of the user
     * @return true if the login attempt is successful
     * @throws Exception if an error occurs
     */
    boolean login(String userID, String password) throws Exception;

    /**
     * Logs in the user as a guest.  If the current customer is registered then a new
     * customer will be created and assigned to the session.  If the current customer
     * is unregistered then it is used.  The customer will be logged in upon completion
     * of this call.
     */
    void loginGuest();

    /**
     * Logs out the customer.
     */
    void logout();

    /**
     * Returns true if the customer has logged in.
     * @return true if the the user is logged in
     */
    boolean isLoggedIn();

    /**
     * Returns true if the current user is a guest; that is, is not a registered user.
     * @return true if the user is a guest
     */
    boolean isGuest();

    /**
     * Returns true if the current user is a registered user.
     *
     * @return true if the customer is registered
     */
    boolean isRegistered();

    /**
     * Registers the customer with the specified user name and password.  If the current
     * customer is already a registered user then a new user is created as part of the call.
     * If the current customer is a guest user then it assigned the user name and password.
     *
     * @param userID   the user name - currently the user email and user name are one and the same
     * @param password the user password
     * @return the newly registered customer, or null if the restration failed
     */
    ICustomer register(String userID, String password);

    /**
     *  Gets a unique identifier for the session.  The id must be unique accross
     *  VMs, time, and instances of the webserver.
     *
     * @return the unique identifier of this <code>ICommerceSession</code>
     */
    Integer getId();

    /**
     * Gets current date and time of this <code>ICommerceSession</code>.
     * Decisions that are based on Session type information can get everything from a single object,
     * making it possible to simulate sessions in the past or future.
     *
     * @return the current time of this <code>ICommerceSession</code>
     */
    long getCurrentTime();

    /**
     * Returns the time of the user's last request to the site.  This is set at the beginning of
     * each request.
     *
     * @return the time of the user's last request, or -1 if this is the first request
     */
    long getLastRequestStartTime();

    /**
     * Sets the time of the user's last request to the site.
     *
     * @param time the time of the user's last request, or -1 if this is the first request
     */
    void setLastRequestStartTime(long time);

    /**
     * Returns the time of the user's last request to the site.  This is set at the end of
     * each request, so calling getLastRequestTime() during a request will return
     * the time the previous request was sent.
     *
     * If this is the first request then -1 is returned
     * @return the time that the user's last request finished
     */
    long getLastRequestFinishTime();

    /**
     * Sets the time that the user's last request finished.
     * Called at the end of each request but before logging the REQUEST_FINISH event.
     *
     * @param time the time the user's last request finished
     */
    void setLastRequestFinishTime(long time);

    /**
     * Returns the <code>Locale</code> of this <code>ICommerceSession</code>.
     *
     * @return the <code>Locale</code> of this <code>ICommerceSession</code>
     */
    Locale getLocale();

    /**
     * Set the <code>Locale</code> of this <code>ICommerceSession</code>.
     * @param locale the <code>Locale</code> of this <code>ICommerceSession</code>
     */
    void setLocale(Locale locale);

    /**
     * Returns the primary key of the customer associated with this <code>ICommerceSession</code>.
     *
     * @return the primary key of the customer associated with this <code>ICommerceSession</code>
     */
    IPrimaryKey getCustomerPk();

    /**
     * Returns the primary key of the basket associated with this <code>ICommerceSession</code>.
     *
     * @return the primary key of the basket associated with this <code>ICommerceSession</code>
     */
    IPrimaryKey getBasketPk();

    /**
     * Starts a new basket, abandoning the old basket.
     */
    void startNewBasket();

    /**
     * Returns a <code>List</code> of source code strings associated with this <code>ICommerceSession</code>.
     * If there is more than one code, the list is kept in the order in which the shopper
     * entered the source codes. There are no duplicates in the list: If the shopper enters the sequence
     * A,B,C,A,A,C the stored list is A,B,C; that is, reinsertion of the same value does not affect order.
     * The collection is empty if there are no source codes for this session.
     *
     * @return a non-null <code>List</code> of source code values associated with this <code>ICommerceSession</code>
     */
    List<IPrimaryKey> getSourceCodePks();

    /**
     * Returns the identifiers of all <code>ISurvey</code>s presented during this <code>ICommerceSession</code>.
     * The collection is empty if no surveys have been presented in this session.
     *
     * @return a non-null collection of the identifiers of all <code>ISurvey</code>s presented
     * during this <code>ICommerceSession</code>
     */
    Collection getSurveyPresentedIds();

    /**
     * Returns a collection of all <code>ISurvey</code>s presented during this <code>ICommerceSession</code>.
     * The collection is empty if no surveys have been presented in this session.
     *
     * @return a non-null collection of <code>ISurvey</code>s presented during this session
     */
    Collection getSurveysPresented();

    /**
     * Adds a survey to this <code>ICommerceSession</code>.
     *
     * @param survey the identifier of the survey to add
     */
    void addSurveyPresented(Integer survey);

    /**
     * Removes a survey from this <code>ICommerceSession</code>.
     *
     * @param surveyID the identifier of the survey to remove
     */
    void removeSurveyPresented(Integer surveyID);

    /**
     * Returns the identifiers of all <code>ISurvey</code>s submitted during this <code>ICommerceSession</code>.
     *
     * @return a non-null collection of identifiers of surveys submitted during this session
     */
    Collection getSurveySubmittedIds();

    /**
     * Returns the <code>ISurvey</code>s submitted during this <code>ICommerceSession</code>.
     *
     * @return a non-null collection of surveys submitted during this session
     */
    Collection getSurveysSubmitted();

    /**
     * Adds a survey identifier to this <code>ICommerceSession</code>.
     * Called when a user has submitted (filled in) a survey.
     *
     * @param survey the identifier of the survey to add
     */
    void addSurveySubmitted(Integer survey);

    /**
     * Removes a survey identifier from this <code>ICommerceSession</code>.
     *
     * @param surveyID the identifier of the survey to remove
     */
    void removeSurveySubmitted(Integer surveyID);

    /**
     * Returns the current customer.  This is the best guess based on cookie
     * information stored on the user's machine.  Use isLoggedIn() to make sure
     * the user has provided their password to prove who they are.
     *
     * @return the customer associated with this session
     */
    ICustomer getCustomer();

    /**
     * Returns the <code>ICustomer</code> associated with this <code>ICommerceSession</code>.
     * When <code>createIfRequired</code> is true, the returned customer is guaranteed to be
     * non-null and valid. Otherwise, if there is no valid customer for this session, this
     * method returns null.
     *
     * @param createIfRequired true to guarantee that a customer is associated with this session
     * @return the customer associated with this session
     */
    ICustomer getCustomer(boolean createIfRequired);

    /**
     * Sets the customer associated with this <code>ICommerceSession</code>.
     *
     * @param customer the customer for this session
     */
    void setCustomer(ICustomer customer);


    /**
     * Returns true if this <code>ICommerceSession</code> is finalized.
     *
     * @return true if this session is finalized
     * @deprecated As of version 5.3, <code>ICommerceSession</code> cannot be finalized or expired.
     */
    boolean isFinalized();

    /**
     * Sets the finalized state of this <code>ICommerceSession</code>.
     * @param flag true if this commerce session is finalized, false otherwise
     * @deprecated As of version 5.3, <code>ICommerceSession</code> cannot be finalized or expired.
     */
    void setFinalized(boolean flag);

    /**
     * Returns true if this commerce session has expired.
     * @return true if this session has expired
     * @deprecated As of version 5.3, <code>ICommerceSession</code> cannot be finalized or expired.
     */
    boolean isExpired();

    /**
     * Returns the session attribute that has the given key.
     *
     * @param key the key of the attribute to return
     * @return a session attribute
     */
    Object getAttribute(String key);

    /**
     * Sets a session attribute.
     * @param key the key of the attribute
     * @param value the attribute value
     */
    void setAttribute(String key, Object value);

    /**
     * Removes an attribute from this session.
     * @param key the key of the attribute to remove
     */
    void removeAttribute(String key);

    /**
     * Returns the length of time the current user has been on the site.
     * @return how long the current user has been on the site
     */
    BigDecimal getTimeOnSite();

    /**
     * Sets the current request for this <code>ICommerceSesssion</code>.
     *
     * @param httpRequest the current <code>HttpServletRequest</code> for this session
     */
    void setCurrentRequest(HttpServletRequest httpRequest);

    /**
     * Returns the current request for this <code>ICommerceSesssion</code>.
     *
     * @return the current <code>HttpServletRequest</code> for this session
     */
    HttpServletRequest getCurrentRequest();
    
    /**
     * Returns the String ID value for the ABTest assigned to this shopper.
     * @return
     */
    String getABTestID();
    
    /**
     * Sets the String ID value for the ABTest assigned to this shopper.
     * @param abtestID
     */
    void setABTestID(String abtestID);
    
    /**
     * Returns the String ID value for the ABTestVersion assigned to this shopper.
     * @return
     */    
    String getABTestVersionID();
    
    /**
     * Sets the String ID value for the ABTestVersion assigned to this shopper.
     * @param abtestID
     */
    void setABTestVersionID(String abtestVersionID);
    
    /**
     * Returns the int days duration value for the ABTest defined for this test.
     * @return
     */
    int getABTestDuration();
    
    /**
     * Sets the int days duration value for the ABTest defined for this test.
     * @param duration
     */
    void setABTestDuration(int duration);

    /**
     *  Creates a DigitalCoupon entity by the digital coupon code and logs
     *  the event passed as a parameter.
     *  @param  String code - Digital Coupon code
     *          String event - event name as specified in DBSessionLogger, e.g. DIGITAL_COUPON_ENTERED
     */
    //todo:huw public void addDigitalCoupon( String code, String event );

    /**
     *  Removes a digital coupon to the session
     */
    //todo:huw public void removeDigitalCoupon( DigitalCoupon digitalCoupon );

    /**
     *  Returns the PrimaryKeys of all Campaigns triggered in this session
     */
    //todo:huw public Collection getActiveCampaignPKs();

    /**
     *  Adds a campaign to the session
     */
    //todo:huw public void activateCampaign( Campaign campaign );

    /**
     *  Removes a campaign from the session
     */
    //todo:huw public void deactivateCampaign( IPrimaryKey campaignPK );


    /**
     *  Returns the PrimaryKeys of all Promotions triggered in this session
     */
    //todo:huw public Collection getActivePromotionPKs();

    /**
     *  Adds a campaign to the session
     */
    //todo:huw public void activatePromotion( Promotion promotion );

    /**
     *  Removes a campaign from the session
     */
    //todo:huw public void deactivatePromotion( IPrimaryKey promotionPK );

    /**
     * Returns IDs of all Surveys presented during this session as a Collection of Integers
     */
    //todo:huw public Collection getActiveSurveyIDs();

    /**
     * Adds a survey to the session
     */
    //todo:huw public void activateSurvey(Integer surveyID);

    /**
     * Removes a survey from the session
     */
    //todo:huw public void deactivateSurvey(Integer surveyID);

}
